package com.cskaoyan.service;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.admin.PageAdmins;
import com.cskaoyan.bean.admin.bo.AdminListBo;
import com.cskaoyan.bean.admin.bo.CreateAdminBo;
import com.cskaoyan.bean.admin.bo.DeleteAdminBO;
import com.cskaoyan.bean.admin.vo.CreateAdminVo;
import com.cskaoyan.bean.auth.bo.AuthLoginBo;
import com.cskaoyan.exeception.BrockenHeartOfMing;
import com.cskaoyan.mapper.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @HJL
 */
@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private StorageMapper storageMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    SystemPermissionMapper systemPermissionMapper;
    @Autowired
    StorageService storageService;


    //查询管理员列表 按分页  注意： 管理员表存的图片有可能被伪删除了，要删除这个管理员表的avatar内容
    @Override
    public PageAdmins getAdminList(AdminListBo bo) {
        //分页
        PageHelper.startPage(bo.getPage(), bo.getLimit());
        AdminExample example = new AdminExample();
        //排序
        example.setOrderByClause(bo.getSort() + " " + bo.getOrder());
        AdminExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);//未删除的
        String username = bo.getUsername();
        if (StringUtils.hasText(username)) {
            criteria.andUsernameLike("%" + username + "%");//这里需要加%
        }
        List<Admin> admins = adminMapper.selectByExample(example);
        //检查头像是否有效，并置空无效的
        for (Admin admin : admins) {
            clearInvalidAvatar(admin);
        }


        //获得分页信息
        PageInfo<Admin> adminPageInfo = new PageInfo<>(admins);
        long total = adminPageInfo.getTotal();
        PageAdmins pageAdmins = new PageAdmins();
        pageAdmins.setAdmins(admins);
        pageAdmins.setTotal(total);
        return pageAdmins;
    }
    //检查头像是否有效，并置空无效的
    private void clearInvalidAvatar(Admin admin) {
        String avatar = admin.getAvatar();
        boolean isdeleted = storageService.isDeleted(null, avatar);
        if (!isdeleted) return;
        admin.setAvatar("'");
        Admin a = new Admin();
        a.setAvatar("'");
        a.setId(admin.getId());
        a.setUpdateTime(new Date());
        adminMapper.updateByPrimaryKeySelective(a);
    }


    //1 伪删除admin //事务多余了,不用删除头像
    @Override//0 ok , 1 fail
    public int deleteAdmin(DeleteAdminBO bo) {
        //删除admin
        Admin admin = new Admin();
        admin.setId(bo.getId());
        admin.setDeleted(true);
        int deleteAdmin = adminMapper.updateByPrimaryKeySelective(admin);
        //TODO 虽然这一步不应该做，但是这里这么操作会报错 开启事务 互相等待死锁 原因
        //删除avatar
//        StorageExample storageExample = new StorageExample();
//        StorageExample.Criteria storageCriteria = storageExample.createCriteria();
//        storageCriteria.andUrlEqualTo(bo.getAvatar());
//        Storage storage = new Storage();
//        storage.setDeleted(true);
//        int deleteAvatar = storageMapper.updateByExampleSelective(storage, storageExample);
        return 0;
    }

    /**
     * 创建管理员
     * 返回null创建失败（重复或其他）
     *
     * @param bo
     * @return
     */
    //0 查重
    @Override//1 创建admin 2 不用保存avatar到storage，上传文件api保存，这里只存avatar key
    public CreateAdminVo createAdmin(CreateAdminBo bo) {
//        重复检查
        AdminExample countExample = new AdminExample();
        AdminExample.Criteria criteria = countExample.createCriteria();
        criteria.andUsernameEqualTo(bo.getUsername());
        long l = adminMapper.countByExample(countExample);
        if (l > 0) {
            return null;
        }
//        插入
        Admin admin = new Admin();
        admin.setUsername(bo.getUsername());
        admin.setPassword(bo.getPassword());
        admin.setAvatar(bo.getAvatar());
        admin.setRoleIds(bo.getRoleIds());
        Date now = new Date();
        admin.setAddTime(now);
        admin.setUpdateTime(now);
        AdminExample example = new AdminExample();
        int update = adminMapper.insertSelective(admin);
        if (update == 0) {//插入失败
            return null;
        }
        CreateAdminVo vo = new CreateAdminVo();
        vo.setId(admin.getId());
        vo.setUsername(admin.getUsername());
        vo.setPassword(admin.getPassword());
        vo.setAvatar(admin.getAvatar());
        vo.setAddTime(admin.getAddTime());
        vo.setUpdateTime(admin.getUpdateTime());
        vo.setRoleIds(admin.getRoleIds());
        return vo;
    }
        //currentName 没用，可以改别人的名字
    @Override//需要判断是否修改成功吗
    public Admin updateAdmin(String currentName, Admin admin) throws SQLException, IllegalAccessException, BrockenHeartOfMing {
        if (admin == null || admin.getId() == null) {
            throw new SQLException("参数不合法");
        }

        //这里故意制造异常测试
        if ("liming@qq.com".equals(admin.getUsername())) {
            throw new BrockenHeartOfMing("小明同学的失恋异常");
        }

        String updateUsername = admin.getUsername();
        //判断重名
        //1 查原来的用户名 是否修改了用户名 如果修改了 看看是否会重复

        boolean available = isNewNameAvailable(updateUsername, admin.getId());
        if (!available) {
            throw new SQLException("权限控制需要，不允许修改用户名");//现在规定不允许修改 用户用用于权限控制了
        }

        //不重名
        admin.setUpdateTime(new Date());
        int update = adminMapper.updateByPrimaryKeySelective(admin);
        if (update == 0) {
            throw new SQLException("数据库操作失败，请核查");
        }
        Admin updatedAdmin = adminMapper.selectByPrimaryKey(admin.getId());
        return updatedAdmin;
    }

    private boolean isNewNameAvailable(String updateUsername, Integer id) {
        Admin oldAdminInfo = getAdminById(id);
        String oldUsername = oldAdminInfo.getUsername();
        //这里时不允许修改用户名的要求直接返回结果
        //没改名字
        if (oldUsername.equals(updateUsername)) {
            return true;
        }
        //一下为允许修改用户名时 使用
        //改了看是否和已存在的重复
//        AdminExample example = new AdminExample();
//        AdminExample.Criteria criteria = example.createCriteria();
//        criteria.andUsernameEqualTo(updateUsername).andIdNotEqualTo(id);
//        List<Admin> admins = adminMapper.selectByExample(example);
//        if (admins.size() == 0) {
//            return true;
//        }
        return false;
    }

    private Admin getAdminById(Integer id) {
        Admin admin = adminMapper.selectByPrimaryKey(id);
        return admin;
    }

    @Override//总是成功
    public boolean deleteRoleFromAllAdmin(int roleId) {
        //选出包含删除角色id的admin
        AdminExample example = new AdminExample();
        AdminExample.Criteria criteria = example.createCriteria();
        criteria.andRoleIdsLike("%" + roleId + "%");
        List<Admin> admins = adminMapper.selectByExample(example);
        //便利删除这个角色id
        for (Admin admin : admins) {
            List<Integer> roleIds = Arrays.asList(admin.getRoleIds());//不允许在这里调用remove元素的方法，很奇怪
            List<Integer> integers = new ArrayList<>();
            for (Integer id : roleIds) {
                if (id != roleId) {
                    integers.add(id);
                }
            }
            Integer[] updatedRoleIds = integers.toArray(new Integer[0]);
            admin.setRoleIds(updatedRoleIds);

            Admin updateAdmin = new Admin();
            updateAdmin.setId(admin.getId());
            updateAdmin.setRoleIds(updatedRoleIds);
            updateAdmin.setUpdateTime(new Date());
            adminMapper.updateByPrimaryKeySelective(updateAdmin);
        }
        return true;
    }

    @Override
    public Admin login(AuthLoginBo loginBo) {
        String password = loginBo.getPassword();
        String username = loginBo.getUsername();
        Admin login = adminMapper.login(password, username);
        if (login == null) {
            return null;
        }
        return login;
    }


    /**
     * 查询管理员角色
     * <p>
     * by 王得昭
     */
    @Override
    public ArrayList<String> getRoles(Admin admin) {
        ArrayList<String> roleList = new ArrayList<>();
        Integer[] roleIdList = admin.getRoleIds();
        // 查出所有的角色
        RoleExample roleExample = new RoleExample();
        RoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andDeletedEqualTo(false);
        List<Role> roles = roleMapper.selectByExample(roleExample);
        //
        for (Integer roleId : roleIdList) {
            for (Role role : roles) {
                if (roleId == role.getId()) {
                    roleList.add(role.getName());
                }
            }
        }
        return roleList;
    }

    /**
     * 查询管理员权限
     * <p>
     * by 王得昭
     * @return
     */
    @Override
    public ArrayList<String> getPerms(Admin admin) {
        ArrayList<String> permissionList = new ArrayList<>();
        ArrayList<String> systemPermissionList = new ArrayList<>();

        Integer[] roleIds = admin.getRoleIds();
        PermissionExample permissionExample = new PermissionExample();
        PermissionExample.Criteria criteria = permissionExample.createCriteria();
        criteria.andDeletedEqualTo(false);
        List<Permission> permissions = permissionMapper.selectByExample(permissionExample);
        for (Integer roleId : roleIds) {
            if(roleId == 1){ // roleId == 1 全部权限
                systemPermissionList.add("*");
                return systemPermissionList;
            }
            for (Permission permission : permissions) {
                if (permission.getRoleId() == roleId){
                    permissionList.add(permission.getPermission()); // xxx : xxx : xxx
                }
            }
        }

        // 选出所有的 system_perm 权限

        SystemPermissionExample systemPermissionExample = new SystemPermissionExample();
        List<SystemPermission> systemPermissions = systemPermissionMapper.selectByExample(systemPermissionExample);

        for (String permission : permissionList) {
            // 如果为"*",加入全部权限
            if("*".equals(permission)){
                for (SystemPermission systemPermission : systemPermissions) {
                    String api = systemPermission.getApi();
                    if(api!=null){
                        systemPermissionList.add(api);
                    }
                }
                break;
            }
            for (SystemPermission systemPermission : systemPermissions) {
                if (permission.equals(systemPermission.getId())) {
                    systemPermissionList.add(systemPermission.getApi());
                }
            }
        }

        return systemPermissionList;
    }

    @Override
    public int getLastLoginIp(String remoteAddr, Integer adminId) {
        int i = adminMapper.insertLastLoginIp(remoteAddr, adminId);
        return i;
    }

    @Override
    public int getLastLoginTime(Integer adminId) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = df.format(new Date());
        Timestamp ts = Timestamp.valueOf(time);
        return adminMapper.insertLastLoginTime(ts, adminId);
    }
}
